home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
System Booster
/
System Booster.iso
/
Systemmonitors
/
Snoopy
/
Includes
/
macro.i
next >
Wrap
Text File
|
1996-09-26
|
12KB
|
655 lines
IFND MACRO_I
MACRO_I equ 1
;-------------- define a pixel size to both BYTE,WORD and LONG sizes
DEFINE MACRO
\1 equ \2
\1.B equ (\2)/8
\1.W equ (\2)/16
\1.L equ (\2)/32
ENDM
;-------------- some standard defines
CSI equ $9b ; 'Control Sequence Indicator'
ESC equ $1b ; 'ANSI ESCape character'
VERTICALTAB equ $0b ; 'VERTICAL TABulator' (Eine Zeile Hoch)
PALID equ $FFFFFFDE ; Anfang Pal-Bildschirm
CENDVALUE equ $FFFFFFFE ; Ende Copperliste (auch Macro cend)
;-------------- all registers mask
ALLREGISTERS REG D0-D7/A0-A6
;-------------- standard boolean registers
TRUE equ 1
FALSE equ 0
IFND NULL
NULL equ 0
ENDC
;-------------- push/pop all registers on the stack
PUSHALL MACRO
pushm d0-d7/a0-a6
ENDM
PULLALL MACRO
popm d0-d7/a0-a6
ENDM
;-------------- call function \1 (optional: load library \2)
;-------------- NOTE: (to my mind) better than DOSCALL and stuff like that
;-------------- because a6 is only loaded if necesarry
;--------------
CALL MACRO
IFEQ NARG-2
movea.l \2,a6
ENDC
jsr (_LVO\1,a6)
ENDM
;-------------- print \1 using arguments \2 (optional: dosBase = \3)
DPRINTF MACRO
pushm d0-d3/a0-a1/a6
IFGT NARG-1
move.l #\2,D2
ELSE
moveq #0,d2
ENDC
move.l #\1,d1
IFGT NARG-2
CALL VPrintf,\3
ELSE
CALL VPrintf,<(dosBase,pc)>
ENDC
popm d0-d3/a0-a1/a6
ENDM
;-------------- branch to \2 if \1 is uppercase
;--------------
IFUCASE MACRO
cmpi.b #'a',\1
blo\0 \2
cmpi.b #'z',\1
bgt\0 \2
ENDM
;-------------- make data register \1 uppercase
UCASE MACRO
cmpi.b #'a',\1
blo.b .UCASE\@
cmpi.b #'z',\1
bgt.b .UCASE\@
subi.b #('a'-'A'),\1
.UCASE\@
ENDM
;-------------- make data register \1 lowercase
LCASE MACRO
cmpi.b #'A',\1
blo.b .LCASE\@
cmpi.b #'Z',\1
bgt.b .LCASE\@
addi.b #('a'-'A'),\1
.LCASE\@
ENDM
;-------------- branch to \2 if \1 is a digit
IFDIGIT MACRO
cmpi.b #'0',\1
blo.b .DIGIT\@
cmpi.b #'9',\1
bgt.b .DIGIT\@
bra \2
.DIGIT\@
ENDM
;-------------- move BPTR \1 to APTR \2 (scratches d0)
BMOVE MACRO
move.l \1,d0
lsl.l #2,d0
move.l d0,\2
ENDM
;-------------- convert BSTR \1 to ASTR \2 (d0.b is set to the string size)
B2ASTR MACRO
IFNC '\2','a0'
push a0
ENDC
move.l \1,d0
lsl.l #2,d0
movea.l d0,a0
move.b (a0)+,d0
IFNC '\2',a0
move.l a0,\2
pop a0
ENDC
ENDM
;-------------- some "antique" defines
exec.base equ 4
execBase equ 4
customBase equ $dff000
custom.chips equ $dff000
;-------------- cleanup memory area starting at \1, size=\2
CLEARSECTION MACRO
pushm a0/d0
lea \1,a0
move.l #(\2)-1,d0
.CLS\@ clr.b (a0)+
dbra d0,.CLS\@
popm a0/d0
ENDM
;-------------- define an AmigaDOS style version string \1
VERSION MACRO
db 0,'$VER: \1',0
even
ENDM
BRF MACRO
IFEQ NARG-3
tst \1
ELSE
tst\3 \1
ENDC
beq\0 \2
ENDM
;-------------- BRanch\0 to \2 if \1[\3] is TRUE
BRT MACRO
IFEQ NARG-3
tst \1
ELSE
tst\3 \1
ENDC
bne\0 \2
ENDM
;-------------- BRanch\0 to \1 on Low Bit Clear in \2
BRLBC MACRO
btst #0,\1
beq\0 \2
ENDM
;-------------- BRanch\0 to \1 on Low Bit Set in \2
BRLBS MACRO
btst #0,\1
bne\0 \2
ENDM
;-------------- BRanch\0 to \1 on Bit \1 Set in \2
BRBS MACRO
btst \1,\2
bne\0 \3
ENDM
;-------------- BRanch\0 to \1 on Bit \1 Clear in \2
BRBC MACRO
btst \1,\2
beq\0 \3
ENDM
;-------------- compare <ea>-values \1,\2 size=\0 ; scratches d0 or \3
COMPARE MACRO
IFEQ NARG-3
move\0 \1,\3
cmp\0 \2,\3
ELSE
move\0 \1,d0
cmp\0 \2,d0
ENDC
ENDM
;--------------
;-------------- branch to \4 if \1 matches \3 any comparison
;-------------- possible comparisons are ==, !=, <, <=, >, >=
BRANCH MACRO ; \1=Wert 1,\2=Condition Code,\3=Wert 2,\4=Label,[\5=Größe Vergleich]
IFEQ NARG-5
COMPARE\5 \1,\3
ELSE
COMPARE \1,\3
ENDC
IFC '\2','=='
beq\0 \4
ENDC
IFC '\2','!='
bne\0 \4
ENDC
IFC '\2','<='
bls\0 \4
ENDC
IFC '\2','<'
blo\0 \4
ENDC
IFC '\2','>='
bhs\0 \4
ENDC
IFC '\2','>'
bhi\0 \4
ENDC
ENDM
;-------------- openlib \1 and put the base to \2 (version \3)
OPENLIB MACRO
lea \1,a1
IFEQ NARG-3
moveq #\3,d0
ELSE
moveq #0,d0
ENDC
CALL OpenLibrary,<(execBase).w>
move.l d0,\2
tst.l d0
ENDM
;-------------- "save" closing of library \1
CLOSELIB MACRO
tst.l \1
beq.b .Closelib\@
movea.l \1,a1
CALL CloseLibrary,<(execBase).w>
.Closelib\@
ENDM
;-------------- clear stack memory sized \1 in stack register \2
CLEARSTACK MACRO
movem.l d0/\2,-(sp)
move.w #(\1)/2-1,d0
.CLRSTK\@ move.w #0,(\2)+
dbra d0,.CLRSTK\@
movem.l (sp)+,d0/\2
ENDM
;-------------- create stack sized \1 in stack register \2
;-------------- NOTE: this stack has positive offsets, which means you
;-------------- can directly access it with STRUCTURE macros
CREATESTACK MACRO
link \2,#-\1
subi.l #\1,\2
CLEARSTACK \1,\2
ENDM
;-------------- remove local stack sized \1 in stack register \2
ENDSTACK MACRO
addi.l #\1,\2
unlk \2
ENDM
;-------------- minimal function head for function \1 using register mask \2
;-------------- you *MUST* use DONE (or ENDSUB) to end this function;
;-------------- else the assembler will give you a warning
XENTRY MACRO
IFEQ NARG-2 ; Wenn es 2 Argumente gibt
\1_regs reg \2 ; Register sichern
\1 movem.l \1_regs,-(sp) ; Register auf den Stack
ELSE ; Sonst
\1 ; Nur den Funktionsnamen definieren
ENDC ; Ende
ENTRYohneDONEfür set \1_done
ENDM
;-------------- all-purpose function entry macro. Defines function named \1
;-------------- saving the registers \2. Optional: stacksize \3, stackregister \4
;-------------- you *MUST* use DONE (or ENDSUB) to end this function;
;-------------- else the assembler will give you a warning
ENTRY MACRO
IFD IS_LINKABLE
xdef \1
ENDC
XENTRY \1,\2
IFEQ NARG-4
\1_stksize equ \3
\1_stkreg equr \4
CREATESTACK \3,\4
ENDC
ENDM
;-------------- end a function created with ENTRY or XENTRY macros;
;-------------- it cleans up the stack (if one exists) and restores the
;-------------- saved register list
ENDSUB MACRO
IFNC '','\1'
IFND \1
FAIL Die Funktion \1 existiert nicht
ENDC
IFND \1_done
\1_done
ENDC
ELSE
.function_done
ENDC
IFD \1_stksize
ENDSTACK \1_stksize,\1_stkreg
ENDC
IFD \1_regs
movem.l (sp)+,\1_regs
ENDC
ENDM
;-------------- same as ENDSUB but returns with RTS
DONE MACRO
ENDSUB \1
rts
ENDM
;-------------- same as ENDSUB but returns with RTE
DONEEXCEPTION MACRO
ENDSUB \1
rte
ENDM
;-------------- don't use this: internal DEBUG macro
DEBUGALLOWED MACRO
IFD DEBUG_MODE
__DEBUG_VAR
IFC '\1',''
DC.L $7F000
ELSE
DC.L \1
ENDC
ENDC
ENDM
DEBUG MACRO
IFD DEBUG_MODE
move.l a0,-(sp)
move.l \1,-(sp)
movea.l (__DEBUG_VAR),a0
move.l (sp)+,(a0)+
IFGT NARG-1
move.l \2,(a0)+
ENDC
IFGT NARG-2
move.l \3,(a0)+
ENDC
IFGT NARG-3
move.l \4,(a0)+
ENDC
IFGT NARG-4
move.l \5,(a0)+
ENDC
IFGT NARG-5
move.l \6,(a0)+
ENDC
move.l a0,(__DEBUG_VAR)
move.l (sp)+,a0
ENDC
ENDM
;-------------- set or clear flag \3 if \1 matches \2 using comparison \3
SETFLAG MACRO
COMPARE\0 \1,\3
IFC '\2','=='
seq \4
ENDC
IFC '\2','!='
sne \4
ENDC
IFC '\2','<='
sls \4
ENDC
IFC '\2','<'
slo \4
ENDC
IFC '\2','>='
sge \4
ENDC
IFC '\2','>'
sgt \4
ENDC
ENDM
;-------------- BROKEN::::::::::::::::::::::::::::::::::::::::::::::::
IIF MACRO ;\1=ConditionCode,\2=Befehle
IIF_FLAG SET 0
IFC '\1','EQ'
IIF_FLAG SET 1
bne.b .iif\@
ENDC
IFC '\1','NE'
IIF_FLAG SET 1
beq.b .iif\@
ENDC
IFC '\1','LS'
IIF_FLAG SET 1
bgt.b .iif\@
ENDC
IFC '\1','LO'
IIF_FLAG SET 1
bge.b .iif\@
ENDC
IFC '\1','HS'
IIF_FLAG SET 1
blo.b .iif\@
ENDC
IFC '\1','HI'
IIF_FLAG SET 1
bls.b .iif\@
ENDC
IFNE IIF_FLAG-1
FAIL Ungültiger Conditioncode '\1' für IIF-Makro
ENDC
\2
IFEQ NARG-3
bra.b .else\@
.iif\@
\3 **** BROKEN, DON'T USE ****
.else\@
ELSE
.iif\@
ENDC
ENDM
;-------------- optimized clear for data registers
CLEAR_DATAREG MACRO
IFC \*UPPER(\0),.L
moveq #0,\1
ELSE
clr\0 \1
ENDC
ENDM
;-------------- optimized clear for addr registers
CLEAR_ADDRREG MACRO
IFC \*UPPER(\0),.B
clr.b \1,\1
ELSE
suba\0 \1,\1
ENDC
ENDM
;-------------- clear Dx/Ax/anything else
CLEAR_ANYTHING MACRO
IFNC '','\1'
IFEQ \*STRLEN(\1)-3
IFC \*UPPER(\*LEFT(\1,1)),D
CLEAR_DATAREG\0 \1
MEXIT
ENDC
IFC \*UPPER(\*LEFT(\1,1)),A
CLEAR_ADDRREG\0 \1
MEXIT
ENDC
ENDC
clr\0 \1
ENDC
ENDM
;-------------- optimized clear [up to 16 arguments]
OPTIMIZED_CLEAR MACRO
CLEAR_ANYTHING\0 \1
CLEAR_ANYTHING\0 \2
CLEAR_ANYTHING\0 \3
CLEAR_ANYTHING\0 \4
CLEAR_ANYTHING\0 \5
CLEAR_ANYTHING\0 \6
CLEAR_ANYTHING\0 \7
CLEAR_ANYTHING\0 \8
CLEAR_ANYTHING\0 \9
CLEAR_ANYTHING\0 \(10)
CLEAR_ANYTHING\0 \(11)
CLEAR_ANYTHING\0 \(12)
CLEAR_ANYTHING\0 \(13)
CLEAR_ANYTHING\0 \(14)
CLEAR_ANYTHING\0 \(15)
CLEAR_ANYTHING\0 \(16)
ENDM
;-------------- required, because in exec/macros.i another 'CLEAR' is defined
CLEAR SETMAC OPTIMIZED_CLEAR
;-------------- exchange two variables using stack (don't use stack relative args)
XCHG MACRO ;Op1,Op2
IFC \*UPPER(\0),.B
move.w d0,-(sp)
move.b \1,d0
move.b \2,\1
move.b d0,\2
move.w (sp)+,d0
ELSE
move\0 \1,-(sp)
move\0 \2,\1
move\0 (sp)+,\2
ENDC
ENDM
;-------------- same as ++/-- in C
INC MACRO
addq\0 #1,\1
ENDM
DEC MACRO
subq\0 #1,\1
ENDM
;-------------- index calculation for an 2 dimensional array. BROKEN
;--------------
;-------------- INDEX \1=result,\2=x,\3=xsize,\4=xmin,[\5=xmax,\6=y,\7=ysize,\8=ymin]
;--------------
;-------------- Dabei ist
;--------------
;-------------- x/y : Die Elementnummer
;-------------- xsize/ysize : Die Größe eines Elements dieses Typs
;-------------- xmin/ymin : Der Minimalwert für das Element
;-------------- xmax/ymax : Der Maximalwert für das Element
;--------------
;-------------- Eine eindimensionale Liste ist dabei So aufgebaut
;--------------
;-------------- [ Element=0, index=xmin, ,offset=0]
;-------------- [ Element=1, index=xmin+xsize ,offset=xsize]
;-------------- [ Element=2, index=xmin+2*xsize ,offset=2*xsize]
;-------------- ...
;--------------
;-------------- Eine zweidimensionale Liste ist dabei so aufgebaut
;--------------
;-------------- [ Element=0/0, index=xmin, ,offset=0]
;-------------- [ Element=0/1, index=xmin+xsize ,offset=xsize]
;-------------- [ Element=0/2, index=xmax+2*xsize ,offset=2*xsize]
;-------------- ...
;-------------- [ Element=1/0, index=xmin+(xmin-xmax)*xsize ,offset=(xmin-xmax)*xsize]
;-------------- ...
;--------------
INDEX MACRO
move.l #((\2)-(\4))*(\3),\1 ; Result = X-Offset
ENDM
;-------------- Verschiedene direkte 'Branch on Condition'-Befehle, die nicht wie
;-------------- 'BRANCH' extra-komische Vergleiche anstellen müßen.
BRNE MACRO
cmp\4 \1,\2
bne\0 \3
ENDM
BREQ MACRO
cmp\4 \1,\2
beq\0 \3
ENDM
BRLO MACRO
cmp\4 \1,\2
blo\0 \3
ENDM
BRLS MACRO
cmp\4 \1,\2
bls\0 \3
ENDM
BRGT MACRO
cmp\4 \1,\2
bgt\0 \3
ENDM
BRGE MACRO
cmp\4 \1,\2
bge\0 \3
ENDM
BREQ0 MACRO
tst\3 \1
beq\0 \2
ENDM
BRNE0 MACRO
tst\3 \1
bne\0 \2
ENDM
ADDO MACRO
IFC \*LEFT(\1,1),#
IFLE \*RIGHT(\1,\*STRLEN(\1)-1)-8
addq\0 \1,\2
ELSE
addi\0 \1,\2
ENDC
ELSE
add\0 \1,\2
ENDC
ENDM
SUBO MACRO
IFC \*LEFT(\1,1),#
IFLE \*RIGHT(\1,\*STRLEN(\1)-1)-8
subq\0 \1,\2
ELSE
subi\0 \1,\2
ENDC
ELSE
sub\0 \1,\2
ENDC
ENDM
;-------------- copy string \1 to string \2 (both arguments Ax)
STRCPY MACRO ; sourcereg, targetreg
.strcpy\@ move.b (\1)+,(\2)+
bne.s .strcpy\@
ENDM
;-------------- cpu status bits
BITDEF CPUSTATE,EXTENDED,4 ; X
BITDEF CPUSTATE,NEGATIVE,3 ; N
BITDEF CPUSTATE,ZERO,2 ; Z
BITDEF CPUSTATE,OVERFLOW,1 ; V
BITDEF CPUSTATE,CARRY,0 ; C
;-------------- my REMHEAD macro. Only difference to exec/list.i : uses local
;-------------- labels
MYREMHEAD MACRO ; A0-list A1-(destroyed) D0=node
MOVE.L (A0),A1
MOVE.L (A1),D0
BEQ.B .REMHEAD\@
MOVE.L D0,(A0)
EXG.L D0,A1
MOVE.L A0,LN_PRED(A1)
.REMHEAD\@
ENDM
;-------------- define an intuition-style alert()
DEFINE_ALERT MACRO
dc.w 10
dc.b 15,'\1',0,0
ENDM
ENDC
;--------------